﻿// --------------------------------
// <copyright file="ParticleEffect.cs" company="Faculty of Information Technology, Czech Technical University in Prague">
//     This document is shared by Microsoft Public License (MS-PL)
//     For further details please see http://msdn.microsoft.com/en-us/library/ff648068.aspx or license.txt.
// </copyright>
// <author>Vladislav Richter</author>

// <email>richtvl2@fit.cvut.cz</email>

// <date>9. 11. 2011 22:22:37</date>

// <summary>
//
// </summary>
// --------------------------------
using System;
using Microsoft.Xna.Framework;

namespace FITClub.Episode1.Components.Particles.ParticleSystems
{
    /// <summary>
    /// This class is game component that represents stan alone particle effect, automatically generating new particles in accordance with its settings
    /// </summary>
    internal class ParticleEffect : ParticleSystem
    {
        #region FIELDS

        /// <summary>
        /// Initioal position of particles in the system
        /// </summary>
        public Vector3 Position;
        public GameFITClub game;
        Random rnd;
        /// <summary>
        /// Counter used for generating less than 1 particle per frame
        /// </summary>
        int FramesToNextParticle = 0;
        /// <summary>
        /// Settings of this generator
        /// </summary>
        ParticleSettings Config;

        #endregion FIELDS

        #region METHODS

        public ParticleEffect(Game game, Vector3 position, ParticleSettings config)
            : base(game, game.Content)
        {
            this.Position = position;
            this.game = (GameFITClub)game;
            this.Config = config;
            this.rnd = new Random();
            this.settings = config;
        }

        public double GetRandomNumber(double minimum, double maximum)
        {
            return rnd.NextDouble() * (maximum - minimum) + minimum;
        }

        public override void Update(GameTime gameTime)
        {
            if (this.settings.MaxNumberOfFramesToNextParticle > 0)
            {
                if (this.FramesToNextParticle <= 0)
                {
                    this.FramesToNextParticle = rnd.Next(this.settings.MinNumberOfFramesToNextParticle, this.settings.MaxNumberOfFramesToNextParticle + 1);
                    if (this.settings.MaxNumberOfParticlesPerFrame > 0)
                    {
                        int c = rnd.Next(this.settings.MinNumberOfParticlesPerFrame, this.settings.MaxNumberOfParticlesPerFrame + 1);
                        for (int i = 0; i < c; i++)
                        {
                            if (this.settings.LineLength > 0)
                            {
                                Vector3 v = new Vector3((float)(GetRandomNumber(-this.settings.LineLength / 2.0, this.settings.LineLength / 2.0)), 0, 0);
                                this.AddParticle(this.Position + v, Vector3.Zero);
                            }
                            else
                            {
                                this.AddParticle(this.Position, Vector3.Zero);
                            }
                        }
                    }
                }
                else
                {
                    this.FramesToNextParticle--;
                }
            }
            else
            {
                if (this.settings.MaxNumberOfParticlesPerFrame > 0)
                {
                    int c = rnd.Next(this.settings.MinNumberOfParticlesPerFrame, this.settings.MaxNumberOfParticlesPerFrame + 1);
                    for (int i = 0; i < c; i++)
                    {
                        if (this.settings.LineLength > 0)
                        {
                            Vector3 v = new Vector3((float)(GetRandomNumber(-this.settings.LineLength / 2.0, this.settings.LineLength / 2.0)), 0, 0);
                            this.AddParticle(this.Position + v, Vector3.Zero);
                        }
                        else
                        {
                            this.AddParticle(this.Position, Vector3.Zero);
                        }
                    }
                }
            }
            base.Update(gameTime);
        }

        public override void Draw(GameTime gameTime)
        {
            this.SetCamera(this.game.ViewMatrix, this.game.ProjectionMatrix);
            base.Draw(gameTime);
        }

        protected override void InitializeSettings(ParticleSettings settings)
        {
            settings = this.Config;
        }

        #endregion METHODS
    }
}